import { ScaffoldCallToActionTour } from '../index/ScaffoldCallToAction'

## Routing

Similarly to Nuxt,
we define a new page by creating a new `+Page.vue` file.

```vue
<!-- /pages/index/+Page.vue -->
<!-- Environment: browser and server -->

<template>
  This page is rendered to HTML and interactive: <Counter />
</template>

<script setup>
import Counter from '../../components/Counter.vue'
</script>
```

By default, Vike does Filesystem Routing.

```
FILESYSTEM                  URL
/pages/index/+Page.vue      /
/pages/about/+Page.vue      /about
```

We can also define a page's route with a *Route String* (for parameterized routes such as `/movies/@id`) or a *Route Function* (for full programmatic flexibility).

```js
// /pages/index/+route.js

// Note how the two files share the same folder `/pages/index/`; this is how Vike
// knows that `/pages/index/+route.js` defines the route of `/pages/index/+Page.vue`.

// Route Function
export default pageContext => pageContext.urlPathname === '/'

// If we don't create a `+route.js` file then Vike does Filesystem Routing
```


## Render Control

Unlike Nuxt, we control how our pages are rendered.

```js
// /renderer/+onRenderHtml.js
// Environment: server

import { createSSRApp, h } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'

export { onRenderHtml }

async function onRenderHtml(pageContext) {
  const { Page, data } = pageContext
  const app = createSSRApp({
    render: () => h(Page, data)
  })

  const appHtml = await renderToString(app)

  const title = 'Vite SSR'

  return escapeInject`<!DOCTYPE html>
    <html>
      <head>
        <title>${title}</title>
      </head>
      <body>
        <div id="app">${dangerouslySkipEscape(appHtml)}</div>
      </body>
    </html>`
}
```

```js
// /renderer/+onRenderClient.js
// Environment: browser

import { createSSRApp, h } from 'vue'

export { onRenderClient }

async function onRenderClient(pageContext) {
  const { Page, data } = pageContext
  const app = createSSRApp({
    render: () => h(Page, data)
  })
  app.mount('#app')
}
```

> You may see `import { createSSRApp, h } from 'vue'` for the first time,
> but every SSR app actually uses `createSSRApp` and `h`.
>
> Nuxt abstracts this away from us and gives us a slightly faster getting started. But this also means that we
> lose control over a central piece of our app architecture and
> we'll eventually lose more time circumventing Nuxt's limiting black box.

This control enables us to *easily* and *naturally* integrate any tool we want (Vuex, GraphQL, Service Worker, ...).

Note how we defined the files `onRenderClient.js` and `onRenderHtml.js` in a directory called `/renderer/`: that way, we tell Vike to apply the `onRenderHtml()` and `onRenderClient()` hooks to all our pages.

This means we can now create a new page just by defining a new `+Page.jsx` file (the `+route.js` file is optional).

Plus files in `/renderer/` can be overridden. For example, we can override the `onRenderHtml()` and `onRenderClient()` hooks for rendering some of
our pages with a completely different UI framework such as React.


## Data Fetching

Let's now have a look at how to fetch data.

```vue
<!-- /pages/star-wars/movie/+Page.vue -->
<!-- Environment: browser and server -->

<template>
  <h1>{{movie.title}}</h1>
  <p>Release Date: {{movie.release_date}}</p>
  <p>Director: {{movie.director}}</p>
</template>

<script lang="js">
const data = ['movie']
export default { props: data }
</script>
```

```js
// /pages/star-wars/movie/+route.js
// Environment: server

// Route String
export default '/star-wars/@movieId'
```

```js
// /pages/star-wars/movie/+data.js
// Environment: server

import fetch from 'node-fetch'

export async function data(pageContext) {
  // The route parameter of `/star-wars/@movieId` is available at `pageContext.routeParams`
  const { movieId } = pageContext.routeParams

  // By default, +data.js files are loaded and executed only on the server-side
  // which means we can use SQL/ORM queries here.
  const response = await fetch(`https://star-wars.brillout.com/api/films/${id}.json`)
  let movie = await response.json()

  // Our render and hydrate functions we defined earlier pass `pageContext.data` to
  // the root Vue component `Page`; this is where we define it.
  return {
    movie
  }
}
```

That's it for the tour and we have actually already seen most of Vike's interface;
not only is Vike flexible but it's also simple to use!

<ScaffoldCallToActionTour />
